import redis
import time
import json

# 创建redis全局变量
RedisHost='10.4.1.106'
RedisPort = '6383'
RedisStatusDB = '0'
RedisTrackDB = '2'
RedisStatusStoreName = "EVStatusStore"
TrackConnection = redis.Redis(host=RedisHost,port=RedisPort, db=RedisTrackDB)
WriteTrackConnection = redis.Redis(host='10.4.1.10',port='6379', db='2')

ServiceInitTime = time.strftime('%Y%m%d%H%M%S', time.localtime(time.time()))
def timestamp_datetime(value):
    format = '%Y-%m-%d %H:%M:%S'
    # value为传入的值为时间戳(整形)，如：1332888820
    value = time.localtime(int(value))
    ## 经过localtime转换后变成
    ## time.struct_time(tm_year=2012, tm_mon=3, tm_mday=28, tm_hour=6, tm_min=53, tm_sec=40, tm_wday=2, tm_yday=88, tm_isdst=0)
    # 最后再经过strftime函数转换为正常日期格式。
    dt = time.strftime(format, value)
    return dt
def Log(name,value=";",level="debug"):
    name = str(name)
    value = str(value)
    level = str(level)
    if level=="debug":
        #print(name+"|"+value)
        return None
    elif level=="info":
        print(name+"|"+value)
    elif level == "warning":
        print(name+"|"+value)
    elif level == "error":
        print(name+"|"+value)
    elif level == "critical":
        print(name+"|"+value)
    else :
        print("Log else")

    LogPath = "./IOVStatusRefresh" + ServiceInitTime + ".log"
    LogFile = open(LogPath, 'a')
    LogTime = str(time.strftime('%Y%m%d%H%M%S', time.localtime(time.time())))
    LogFile.write(LogTime+"|"+name+"|"+value+"|"+level+'\n')
    LogFile.close()
    return None
def VINStatusForceRefresh(vin):
    Log("VINStatusForceRefresh", "START","info")
    time_VINStatusForceRefresh_start = time.time()
    try:
        StatusResult = TrackConnection.hkeys(vin)
        Log(StatusResult)
        StatusResult.sort(reverse=True)
        Log("type(StatusResult)", type(StatusResult))
        Log("len(StatusResult)", len(StatusResult))
        StatusResultLength = len(StatusResult)
        TrackResultVINDict = {}
        if len(StatusResult) > 0:
            Log("type(StatusResult[0])", type(StatusResult[0]))
            Log("StatusResult[0].decode()", StatusResult[0].decode())

            for index in range(len(StatusResult)):
                VINlastTime = StatusResult[index].decode()
                StatusResultData = TrackConnection.hget(vin, VINlastTime)
                Log("type(StatusResultData)", type(StatusResultData))
                Log("StatusResultData", StatusResultData)
                StatusResultDataDecode = StatusResultData.decode('utf-8')
                StatusResultDataClean = StatusResultDataDecode.replace(' u\'', ' \'')
                StatusResultDataClean = StatusResultDataClean.replace('{u\'', '{\'')
                StatusResultDataClean = StatusResultDataClean.replace('\'', '\"')

                Log("StatusResultDataClean", StatusResultDataClean)
                try:
                    redisTrackResultJSON = json.loads(StatusResultDataClean)
                    eventCode = redisTrackResultJSON['event_code']
                    Log("eventCode", eventCode);
                    terminalCode = redisTrackResultJSON['vin']
                    Log("terminalCode", terminalCode);
                    lat = redisTrackResultJSON['data']['GPS003']['val']  # GPS003	纬度
                    Log("lat", lat);
                    lgt = redisTrackResultJSON['data']['GPS002']['val']  # GPS002	经度
                    Log("lgt", lgt);
                    angle = redisTrackResultJSON['data']['GPS006']['val']  # GPS006	方向
                    Log("angle", angle);
                    speed = redisTrackResultJSON['data']['V019']['val']  # V019	整车车速
                    Log("speed", speed);
                    totalKm = redisTrackResultJSON['data']['V015']['val']  # V015	总里程
                    Log("totalKm", totalKm);
                    enableKm = redisTrackResultJSON['data']['V133']['val']  # V133	续航剩余里程
                    Log("enableKm", enableKm);
                    lastRefreshTime = redisTrackResultJSON['data']['GPS007']['val']  # GPS007	GPS时间
                    Log("lastRefreshTime", lastRefreshTime);
                    soc = redisTrackResultJSON['data']['E010']['val']  # E010	电池电量（SOC）
                    Log("soc", soc);
                    dt = timestamp_datetime(lastRefreshTime[0:10])
                    # Log("lastRefreshTime", lastRefreshTime)
                    # Log("lastRefreshTime[0:10]", lastRefreshTime[0:10])
                    Log("dt", dt);

                    TrackResultVINDict['eventCode'] = eventCode
                    TrackResultVINDict['terminalCode'] = terminalCode
                    TrackResultVINDict['lat'] = lat
                    TrackResultVINDict['lgt'] = lgt
                    TrackResultVINDict['angle'] = angle
                    TrackResultVINDict['speed'] = speed
                    TrackResultVINDict['totalKm'] = totalKm
                    TrackResultVINDict['enableKm'] = enableKm
                    TrackResultVINDict['lastRefreshTime'] = lastRefreshTime
                    TrackResultVINDict['soc'] = soc
                    TrackResultVINDict['dt'] = dt

                    # 能到这，还没exception，说明满足条件的数据

                    Log("Break vin", vin)
                    Log("Break index", index)
                    Log("type(StatusResultData)", type(StatusResultData))
                    Log("type(StatusResultData.decode())", type(StatusResultData.decode()))
                    Log("type(vin)", type(vin))
                    Log("type(vin.decode())", type(vin.decode()))
                    StatusResultString = StatusResultData.decode()
                    StringVIN = vin.decode()
                    try:
                        WriteTrackConnection.hset(RedisStatusStoreName, StringVIN, StatusResultString)
                    except:
                        print("WriteTrackConnection.hset is except")
                    break
                except:
                    Log("TrackConnection.hkeys(vin) except")
                    continue
    except:
        Log("VINStatusForceRefresh:getTrackResult except")
        Log("VINStatusForceRefresh:except vin", vin)
    time_VINStatusForceRefresh_end = time.time()
    Log('VINStatusForceRefresh time cost', time_VINStatusForceRefresh_end - time_VINStatusForceRefresh_end,"info")


def StatusForceRefresh():
    Log("StatusForceRefresh", "START","info")
    time_StatusForceRefresh_start = time.time()
    VINList = TrackConnection.keys()
    Log("type(VINList):"+str(type(VINList)))
    Log("len(VINList):"+str(len(VINList)))
    for index in range(len(VINList)):
        vin = VINList[index]
        Log("VINList index:"+str(index),"VINList vin:"+str(vin.decode()),"info")

        try:
            VINStatusForceRefresh(vin)
        except:
            Log("StatusForceRefresh:getTrackResult except")
            Log("StatusForceRefresh:except vin", vin)
            Log("StatusForceRefresh:except index", index)
            continue
    time_StatusForceRefresh_end = time.time()
    Log('StatusForceRefresh time cost', time_StatusForceRefresh_end - time_StatusForceRefresh_start,"info")

PreStatusList = []
NowStatusList = []
def StatusInitial():
    Log("StatusInitial", "START","info")
    time_StatusInitial_start = time.time()
    # 维护一个keys（vin）的list，监控每个list的size（hlen（key）），一旦发生变化，即进行Status表更新
    global PreStatusList
    global NowStatusList
    # VINStatus = []
    VINList = TrackConnection.keys()
    Log("StatusInitial.type(VINList)"+str(type(VINList)))
    Log("StatusInitial.len(VINList)"+str(len(VINList)))
    for index in range(len(VINList)):
        vin = VINList[index]
        Log("StatusInitial.index:" + str(index))
        Log("StatusInitial.vin:"+str(vin))
        try:
            TrackVINSize = TrackConnection.hlen(vin)
            Log("TrackVINSize", TrackVINSize)
            statusSub = [vin, TrackVINSize, ""]
            NowStatusList.append(statusSub)
        except:
            Log("hlen error")
    Log("len(StatusList):" + str(len(NowStatusList)))
    if len(PreStatusList) == 0 :
        Log("It is first get StatusList,time.sleep(5)")
        PreStatusList = NowStatusList
        time.sleep(5)
        StatusInitial()
    else:
        StatusRefresh()
    time_StatusInitial_end = time.time()
    Log('StatusInitial time cost', time_StatusInitial_end - time_StatusInitial_start,"info")

def StatusRefresh():
    Log("StatusRefresh", "START","info")
    time_StatusRefresh_start = time.time()
    global PreStatusList
    global NowStatusList
    # pre与now进行比较，比较内容是每个Vin对应的TrackVINSize，如果有变化，更新对应的Vin最新状态
    for preIndex in range(len(PreStatusList)):
        for nowIndex in range(len(NowStatusList)):
            if PreStatusList[preIndex][0] == NowStatusList[nowIndex][0]:
                # 如果发现了相同的底盘号，在now内做标记
                NowStatusList[nowIndex][2] = "MATCH"
                if PreStatusList[preIndex][1] == NowStatusList[nowIndex][1]:
                    # 同一个vin内的size么有发生变化
                    continue
                else:
                    # 更新数据
                    Log("相同vin，出现了size差异:vin:",str(PreStatusList[preIndex][0]),"info")
                    Log("相同vin，出现了size差异:preSize:",str(PreStatusList[preIndex][1]),"info")
                    Log("相同vin，出现了size差异:nowSize:", str(NowStatusList[nowIndex][1]), "info")
                    VINStatusForceRefresh(PreStatusList[preIndex][0])
    # 检查，没有MATCH标识的Now的vin
    for nowCheckIndex in range(len(NowStatusList)):
        if NowStatusList[nowCheckIndex][2] == "MATCH":
            continue
        else:
            Log("出现未MATCH vin:", str(NowStatusList[nowCheckIndex][0]), "info")
            VINStatusForceRefresh(NowStatusList[nowCheckIndex][0])

    time_StatusRefresh_end = time.time()
    print('StatusRefresh time cost', time_StatusRefresh_end - time_StatusRefresh_start,"info")
    time.sleep(5)
    StatusInitial()

if __name__ == "__main__":

    StatusForceRefresh()
    StatusInitial()